﻿using System;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using Relocation.Data;
using Ader.TemplateEngine;
using System.Collections.Generic;
using System.Threading;
using Relocation.Com;

namespace Relocation.UI.Xls
{
	/// <summary>
	/// 从DataGridView导出数据到Excel
	/// </summary>
	public class RelocateToExcel
	{
		/// <summary>
		/// 弹出对话框，选择文件保存路径
		/// </summary>
		/// <returns>返回目标文件的路径，如果用户取消选择则返回null</returns>	
		static private String GetFileName()
		{
			return GetFileName(null);
		}

		/// <summary>
		/// 弹出保存文件对话框
		/// </summary>
		/// <param name="fileName">默认文件名</param>
		/// <returns>文件路径</returns>
		static private String GetFileName(String fileName)
		{
			SaveFileDialog dialog = new SaveFileDialog();
			dialog.DefaultExt = ".xls";
			dialog.AddExtension = true;
			dialog.CheckPathExists = true;
			dialog.Filter = "Excel电子表格 (*.xls)|*.xls";
			if (!string.IsNullOrEmpty(fileName))
				dialog.FileName = fileName;
			DialogResult dialogResult = dialog.ShowDialog();
			if (!dialogResult.Equals(DialogResult.OK))
				return null;
			return dialog.FileName;
		}

		static public void RelocateeToExcel(Relocatee relocatees, relocatees_view relocatee_view)
		{
			if (relocatees == null || String.IsNullOrEmpty(relocatees.head))
				return;

			String fileName = GetRelocationFileName(relocatees);
			fileName = GetFileName(fileName);
			if (String.IsNullOrEmpty(fileName))
				return;
			RelocateeToExcel(relocatees, relocatee_view, fileName);
		}

		static public string GetRelocationFileName(Relocatee relocatees)
		{
			String fileName = relocatees.head;
			if (!String.IsNullOrEmpty(relocatees.organization))
				fileName = fileName.Insert(0, relocatees.organization + " -");
			if (!String.IsNullOrEmpty(relocatees.village))
				fileName = fileName.Insert(0, relocatees.village + " - ");

			return ReplcaeInvalidFileNameChar(fileName);

		}

		static public string ReplcaeInvalidFileNameChar(string fileName, char newChar = '-')
		{
			StringBuilder sb = new StringBuilder(fileName);

			foreach (char invalidChar in System.IO.Path.GetInvalidFileNameChars())
			{
				sb.Replace(invalidChar, newChar);
			}
			return sb.ToString();
		}




		static public void RelocateeToExcel(Relocatee relocatees, relocatees_view relocatee_view, string fileName)
		{
			RelocateeToExcel(relocatees, relocatee_view, fileName, true);
		}
		static public void RelocateeToExcel(Relocatee relocatees, relocatees_view relocatee_view, string fileName, bool openFile)
		{

			string templatePath = Application.StartupPath + "\\Template\\Relocatees.xml";
			if (!System.IO.File.Exists(templatePath))
				throw new Exception("Excel模板文件未找到，生成失败！");

			if (!DeleteFile(fileName))
			{
				MessageBox.Show(string.Format("文件：“{0}”\n正在被使用，请关闭文件后重试！", fileName), "导出文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
				return;
			}

			#region 加载关联数据
			relocatees.LoadPlacments();
			relocatees.LoadProject();
			relocatees.LoadRelocateHouse();
			#endregion

			#region 设置其他数据
			int overCount = 8 - relocatees.Placements.Count;
			int yaoqiu_da = relocatees.housetype4 == null ? 0 : (int)relocatees.housetype4;
			int yaoqiu_zhong = (relocatees.housetype3 == null ? 0 : (int)relocatees.housetype3) + (relocatees.housetype2 == null ? 0 : (int)relocatees.housetype2);
			int yaoqiu_xiao = relocatees.housetype1 == null ? 0 : (int)relocatees.housetype1;
			bool zhuanhun = ((System.DateTime.Now.Millisecond + GetRandom(20, 0)) % 2) == 1;		//是否是砖混（随机）
			int chaiqianmianji = GetRandom(250, 70);			//拆迁面积（70-250随机）
			string Zhen = GetTownByVillage(relocatees.village, GetTownVillage());	//镇 
			#endregion

			#region 初始化模板引擎
			TemplateManager tm = TemplateManager.FromFile(templatePath);
			tm.SilentErrors = true;
			tm.Functions.Add("DateToString", new TemplateFunction(DateToString));
			tm.Functions.Add("sum", new TemplateFunction(sum));
			tm.Functions.Add("DateAddMonth", new TemplateFunction(DateAddMonth));
			tm.SetValue("Zhen", Zhen);
			tm.SetValue("yaoqiu_da", yaoqiu_da);
			tm.SetValue("yaoqiu_zhong", yaoqiu_zhong);
			tm.SetValue("yaoqiu_xiao", yaoqiu_xiao);
			tm.SetValue("relocatee", relocatees);
			tm.SetValue("relocatee_view", relocatee_view);
			tm.SetValue("OverCount", overCount > 0 ? overCount : 0);
			tm.SetValue("zhuanhun", zhuanhun);
			tm.SetValue("chaiqianmianji", chaiqianmianji);
			#endregion

			//写入文件
			System.IO.File.AppendAllText(fileName, tm.Process(), Encoding.UTF8);

			if (openFile)
				OpenFile(fileName);

		}

		static public void RelocateViewToExcel(List<relocatees_view> list)
		{
			string fileName = GetFileName("地等项目公示表");
			if (string.IsNullOrEmpty(fileName))
				return;
			RelocateViewToExcel(list, fileName);
		}

		static public void RelocateViewToExcel(List<relocatees_view> list, string fileName)
		{
			string templatePath = Application.StartupPath + "\\Template\\RelocateView.xml";
			if (!System.IO.File.Exists(templatePath))
				throw new Exception("Excel模板文件未找到，生成失败！");

			if (!DeleteFile(fileName))
			{
				MessageBox.Show(string.Format("文件：“{0}”\n正在被使用，请关闭文件后重试！", fileName), "导出文件", MessageBoxButtons.OK, MessageBoxIcon.Information);
				return;
			}

			int ExpandedRowCount = list.Count + 3;
			TemplateManager tm = TemplateManager.FromFile(templatePath);
			tm.SilentErrors = true;
			tm.Functions.Add("DateToString", new TemplateFunction(DateToString));
			tm.Functions.Add("sum", new TemplateFunction(sum));
			tm.Functions.Add("GetArea", new TemplateFunction(GetArea));
			tm.Functions.Add("NullToZero", new TemplateFunction(NullToZero));
			tm.SetValue("list", list);
			tm.SetValue("ExpandedRowCount", ExpandedRowCount);


			//写入文件
			System.IO.File.AppendAllText(fileName, tm.Process(), Encoding.UTF8);

			OpenFile(fileName);

		}

		static public object GetArea(object[] args)
		{
			if (args == null || args.Length < 1)
				return "";
			relocatees_view view = args[0] as relocatees_view;
			if (view == null)
				return "";

			string[] array = new string[7];
			array[0] = GetAreaString(view.housetype5, "50");
			array[1] = GetAreaString(view.housetype1, "70");
			array[2] = GetAreaString(view.housetype2, "90");
			array[3] = GetAreaString(view.housetype3, "110");
			array[4] = GetAreaString(view.housetype4, "130");
			array[5] = GetAreaString(view.housetype6, "储藏室");
			array[6] = GetAreaString(view.housetype7, "门市");

			string values = string.Join("、", array);
			while (values.Contains("、、"))
				values = values.Replace("、、", "、");
			values = values.StartsWith("、") ? values.Remove(0, 1) : values;
			values = values.EndsWith("、") ? values.Remove(values.Length - 1, 1) : values;
			return values;
		}

		static string GetAreaString(int? count, string name)
		{

			if (count.IsGreaterThanZero())
			{
				StringBuilder sb = new StringBuilder();
				bool isGreaterThanZero = count.IsGreaterThanZero();
				for (int i = 0; i < count.Value; i++)
				{
					sb.Append((sb.Length > 0 && isGreaterThanZero) ? "、" : string.Empty);
					sb.Append(isGreaterThanZero ? name : string.Empty);
				}
				return sb.ToString();
			}
			return string.Empty;

		}

		static public object GetIntString(object[] values)
		{
			if (values != null && values.Length > 0)
			{
				int? value = values[0] as int?;
				return value.ToInt().ToString();
			}
			else
			{
				return "0";
			}
		}

		static public object NullDefault(object[] values)
		{
			if (values != null && values.Length > 1)
			{
				return values[0] == null ? values[1] : values[0];
			}
			return "";
		}

		static public object NullToZero(object[] values)
		{
			return (values == null || values[0] == null) ? 0 : values[0];
		}

		/// <summary>
		/// 打开文件
		/// </summary>
		/// <param name="fileName">文件完整路径</param>
		static void OpenFile(string fileName)
		{
			if (System.IO.File.Exists(fileName))
			{
				ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)
				{
					try
					{
						Process.Start(fileName);
					}
					catch (Exception)
					{
					}
				}));
			}
		}

		/// <summary>
		/// 删除文件
		/// </summary>
		/// <param name="fileName">文件完整路径</param>
		/// <returns>文件是否成功删除</returns>
		static bool DeleteFile(string fileName)
		{
			if (System.IO.File.Exists(fileName))
			{
				try
				{
					System.IO.File.Delete(fileName);
					return true;
				}
				catch (Exception ex)
				{
					System.Diagnostics.Debug.WriteLine(ex);
					return false;
				}
			}
			return true;
		}

		static int GetRandomSeed()
		{
			byte[] bytes = new byte[4];
			System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
			rng.GetBytes(bytes);
			return BitConverter.ToInt32(bytes, 0);
		}

		private static int GetRandom(int max, int min)
		{
			Random random = new Random(GetRandomSeed());
			return random.Next(min, max);
		}

		static public object DateAddMonth(object[] args)
		{
			if (args == null || args.Length < 2)
				return "";
			try
			{
				if (args[0] is DateTime)
				{
					DateTime dt = Convert.ToDateTime(args[0]);
					return dt.AddMonths(Convert.ToInt16(args[1]));
				}
				else
				{
					return "";
				}
			}
			catch (Exception)
			{
				return "";
			}
		}

		static public object DateToString(object[] args)
		{
			if (args == null || args.Length < 1)
				return "";

			if (!(args[0] is DateTime))
				return "";
			return ((DateTime)args[0]).ToString("yyyy.MM.dd");
		}


		static public object sum(object[] args)
		{
			if (args == null || args.Length < 2)
				return "";
			try
			{
				double dec1 = Convert.ToDouble(args[0]);
				double dec2 = Convert.ToDouble(args[1]);
				return dec1 + dec2;
			}
			catch (Exception)
			{
				return 0;
			}
		}

		static public string GetTownByVillage(string villageName, Dictionary<string, string> town_Village)
		{
			foreach (var key in town_Village.Keys)
			{
				if (villageName.Contains(key))
					return town_Village[key];
			}
			return string.Empty;
		}


		static public Dictionary<string, string> GetTownVillage()
		{
			Dictionary<string, string> townVillage = new Dictionary<string, string>();
			townVillage.Add("新桥", "开发区");
			townVillage.Add("秦河", "开发区");
			townVillage.Add("焦家", "开发区");

			townVillage.Add("宁兴", "太白镇");
			townVillage.Add("安民", "太白镇");
			townVillage.Add("花园", "太白镇");
			townVillage.Add("永兴", "太白镇");
			townVillage.Add("宁西", "太白镇");

			townVillage.Add("黄山", "姑孰镇");
			townVillage.Add("五联", "姑孰镇");
			townVillage.Add("竹山", "姑孰镇");
			townVillage.Add("宝塔", "姑孰镇");
			return townVillage;
		}
	}

	public delegate string VauleFormaterHandler(Object value, string fieldName);

}
